package com.example.projectmanagement.util;

import org.owasp.html.HtmlPolicyBuilder;
import org.owasp.html.PolicyFactory;
import org.springframework.stereotype.Component;

import java.util.regex.Pattern;

/**
 * XSS防护工具类
 */
@Component
public class XssUtil {
    
    /**
     * 检测是否包含敏感的XSS内容
     * @param content 要检测的内容
     * @return 如果包含敏感内容返回true，否则返回false
     */
    public static boolean containsSensitiveXssContent(String content) {
        if (content == null || content.isEmpty()) {
            return false;
        }

        // 统一规范化：转换为小写并处理编码
        String normalized = normalizeContent(content);

        // 更全面的检测模式
        String[] sensitivePatterns = {
                // 脚本标签（各种变体）
                "<script", "</script", "script>", "script/>",
                // 事件处理器
                "onload\\s*=", "onerror\\s*=", "onclick\\s*=", "onmouseover\\s*=",
                "onfocus\\s*=", "onblur\\s*=", "onsubmit\\s*=", "onreset\\s*=",
                "onselect\\s*=", "onchange\\s*=", "onkeypress\\s*=", "onkeydown\\s*=",
                // JavaScript协议
                "javascript\\s*:", "vbscript\\s*:", "data\\s*:", "livescript\\s*:",
                // 危险函数
                "eval\\s*\\(", "alert\\s*\\(", "confirm\\s*\\(", "prompt\\s*\\(",
                "document\\.cookie", "document\\.location", "window\\.location",
                "document\\.write", "document\\.writeln",
                "setinterval\\s*\\(", "settimeout\\s*\\(", "expression\\s*\\(",
                "fromcharcode\\s*\\(", "\\\\.fromcharcode\\s*\\(",
                // 危险标签和属性
                "<iframe", "<embed", "<object", "<applet", "<meta",
                "style\\s*=", "src\\s*=", "href\\s*=",
                // SVG相关
                "<svg", "<math",
                // 其他危险模式
                "base64", "addeventlistener", "getelementbyid",
                "innerhtml\\s*=", "outerhtml\\s*="
        };

        for (String pattern : sensitivePatterns) {
            if (java.util.regex.Pattern.compile(pattern, Pattern.CASE_INSENSITIVE)
                    .matcher(normalized).find()) {
                return true;
            }
        }

        // 检测HTML标签属性中的XSS
        if (containsDangerousAttributes(normalized)) {
            return true;
        }

        return false;
    }

    private static String normalizeContent(String content) {
        // 基础规范化：转小写，处理简单编码
        String normalized = content.toLowerCase();

        // 处理常见的HTML实体编码
        normalized = normalized.replace("&lt;", "<")
                .replace("&gt;", ">")
                .replace("&quot;", "\"")
                .replace("&#x27;", "'")
                .replace("&#x2f;", "/")
                .replace("&#x60;", "`")
                .replace("&amp;", "&");

        // 移除多余空白字符
        normalized = normalized.replaceAll("\\s+", " ");

        // 移除注释（可选，根据需求）
        normalized = normalized.replace("<!--", "").replace("-->", "");

        return normalized;
    }

    private static boolean containsDangerousAttributes(String content) {
        // 检测属性中的XSS模式
        String[] dangerousAttrPatterns = {
                "\\s+on\\w+\\s*=",                    // 任意on事件
                "\\s+style\\s*=[^>]*expression\\s*\\(", // CSS表达式
                "\\s+href\\s*=[^>]*javascript\\s*:",   // href中的javascript
                "\\s+src\\s*=[^>]*javascript\\s*:"     // src中的javascript
        };

        for (String pattern : dangerousAttrPatterns) {
            if (java.util.regex.Pattern.compile(pattern, Pattern.CASE_INSENSITIVE)
                    .matcher(content).find()) {
                return true;
            }
        }
        return false;
    }
    
    /**
     * 清理纯文本内容
     * @param textContent 原始文本内容
     * @return 清理后的安全文本内容
     */
    public static String sanitizeText(String textContent) {
        if (textContent == null || textContent.isEmpty()) {
            return textContent;
        }
        // 对于纯文本，我们可以进行HTML转义
        return textContent
                .replace("&", "&amp;")
                .replace("<", "&lt;")
                .replace(">", "&gt;")
                .replace("\"", "&quot;")
                .replace("'", "&#x27;");
    }
}